package sudoku.data;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class ForceChainButton {

  private int i;
  private int j;
  private List<Candidate> kandidaadid;

  public ForceChainButton(int i, int j, boolean[] kandidaadid) {
    this.i = i;
    this.j = j;

    this.kandidaadid = new ArrayList<Candidate>();
    for (int k = 0; k < kandidaadid.length; k++) {
      if (kandidaadid[k]) {
        this.kandidaadid.add(new Candidate(k));
      }
    }
  }

  public int getI() {
    return i;
  }

  public int getJ() {
    return j;
  }

  public List<Candidate> getKandidaadid() {
    return kandidaadid;
  }

  public void resetKandidaadid() {
    for (Candidate c : kandidaadid) {
      c.setForceDown(0);
      c.setForceUp(0);
    }
  }

  public Candidate getKandidaat(Candidate c) {
    int indexOf = kandidaadid.indexOf(c);
    if (indexOf != -1) {
      return kandidaadid.get(indexOf);
    }
    return null;
  }

  @Override
  public String toString() {
    return "[i:" + i + "|j:" + j + "|k:" + Arrays.toString(kandidaadid.toArray()) + "]";
  }

  public static class Candidate {
    private int kandidaat;
    private int forceUp;
    private int forceDown;

    public Candidate(int kandidaat) {
      this.kandidaat = kandidaat;
      forceUp = 0;
      forceDown = 0;
    }

    public int getKandidaat() {
      return kandidaat;
    }

    public boolean isForceDown() {
      return forceDown != 0;
    }

    public int getForceDown() {
      return forceDown;
    }

    public void setForceDown(int forceDown) {
      this.forceDown = forceDown;
    }

    public boolean isForceUp() {
      return forceUp != 0;
    }

    public int getForceUp() {
      return forceUp;
    }

    public void setForceUp(int forceUp) {
      this.forceUp = forceUp;
    }

    @Override
    public boolean equals(Object obj) {
      if (obj != null && obj instanceof Integer) {
        return ((Integer) obj).intValue() == kandidaat;
      }
      if (obj != null && obj instanceof Candidate) {
        return ((Candidate) obj).kandidaat == kandidaat;
      }
      return super.equals(obj);
    }

    @Override
    public int hashCode() {
      return new Integer(kandidaat).hashCode();
    }

    @Override
    public String toString() {
      return "(" + (kandidaat + 1) + "|u:" + forceUp + "|d:" + forceDown + ")";
    }
  }

  public static class FilterCandidate {
    private int i;
    private int j;
    private int kandidaat;

    public FilterCandidate(int i, int j, int kandidaat) {
      this.i = i;
      this.j = j;
      this.kandidaat = kandidaat;
    }

    public int getI() {
      return i;
    }

    public int getJ() {
      return j;
    }

    public int getKandidaat() {
      return kandidaat;
    }

    @Override
    public boolean equals(Object obj) {
      if (obj != null && obj instanceof FilterCandidate) {
        FilterCandidate c = (FilterCandidate) obj;
        return c.kandidaat == kandidaat && c.i == i && c.j == j;
      }
      return super.equals(obj);
    }

    @Override
    public int hashCode() {
      return new Integer(kandidaat).hashCode();
    }

    @Override
    public String toString() {
      return "(i:" + i + "|j:" + j + "|k:" + (kandidaat + 1) + ")";
    }
  }

}
